/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lvyh.lightframe.cloud.business.usercenter.service.impl;

import com.google.common.collect.Ordering;
import com.lvyh.lightframe.cloud.business.usercenter.bean.UcSysMenuBean;
import com.lvyh.lightframe.cloud.business.usercenter.bean.UcSysRoleBean;
import com.lvyh.lightframe.cloud.business.usercenter.bean.UcSysRoleMenuBean;
import com.lvyh.lightframe.cloud.business.usercenter.service.SysMenuService;
import com.lvyh.lightframe.cloud.business.usercenter.service.UserCenterMainDataService;
import com.lvyh.lightframe.cloud.common.model.SysMenu;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class SysMenuServiceImpl implements SysMenuService {

    @Autowired
    private UserCenterMainDataService userCenterMainDataService;

    public boolean removeById(Integer id) throws Exception {
        return userCenterMainDataService.deleteUcSysMenu(id);
    }

    public Integer getRoleInfoByMenuId(Integer menuId) throws Exception {
        UcSysRoleMenuBean condition = new UcSysRoleMenuBean();
        condition.setMenuId(menuId);
        List<UcSysRoleMenuBean> sysRoleMenuList = userCenterMainDataService.selectUcSysRoleMenu(condition);
        return !CollectionUtils.isEmpty(sysRoleMenuList) ? sysRoleMenuList.get(0).getRoleId() : 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void setMenuToRole(Integer roleId, List<Integer> menuIds) throws Exception {
        UcSysRoleMenuBean condition = new UcSysRoleMenuBean();
        condition.setRoleId(roleId);
        List<UcSysRoleMenuBean> sysRoleMenuList = userCenterMainDataService.selectUcSysRoleMenu(condition);
        if (!CollectionUtils.isEmpty(sysRoleMenuList)) {
            for (UcSysRoleMenuBean sysRoleMenuBean : sysRoleMenuList) {
                userCenterMainDataService.deleteUcSysRoleMenu(sysRoleMenuBean.getId());
            }
        }

        if (!CollectionUtils.isEmpty(menuIds)) {
            for (Integer menuId : menuIds) {
                UcSysRoleMenuBean sysRoleMenuBean = new UcSysRoleMenuBean();
                sysRoleMenuBean.setRoleId(roleId);
                sysRoleMenuBean.setMenuId(menuId);
                userCenterMainDataService.saveUcSysRoleMenu(sysRoleMenuBean);
            }
        }
    }

    @Override
    public List<SysMenu> findByRoles(List<Integer> roleIds) throws Exception {
        UcSysRoleMenuBean condition = new UcSysRoleMenuBean();
        condition.setRoleIds(roleIds);
        List<UcSysRoleMenuBean> sysRoleMenuList = userCenterMainDataService.selectUcSysRoleMenu(condition);

        List<Integer> menuIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(sysRoleMenuList)) {
            for (UcSysRoleMenuBean sysRoleMenuBean : sysRoleMenuList) {
                menuIds.add(sysRoleMenuBean.getMenuId());
            }
        }

        List<UcSysMenuBean> sysMenuList = getSysMenuList(menuIds, null, null);
        sysMenuList.sort(Ordering.natural().onResultOf(UcSysMenuBean::getSort));

        List<SysMenu> result = convert(sysMenuList);
        return result;
    }

    private List<UcSysRoleMenuBean> getSysRoleMenuList(List<Integer> roleIds) throws Exception {
        UcSysRoleMenuBean condition = new UcSysRoleMenuBean();
        condition.setRoleIds(roleIds);
        return userCenterMainDataService.selectUcSysRoleMenu(condition);
    }

    private List<UcSysMenuBean> getSysMenuList(List<Integer> menuIds, Integer hidden, Integer type) throws Exception {
        UcSysMenuBean condition = new UcSysMenuBean();
        condition.setIds(menuIds);
        condition.setHidden(hidden);
        condition.setType(type);
        return userCenterMainDataService.selectUcSysMenu(condition);
    }

    @Override
    public List<SysMenu> findByRoleCodes(List<String> roleCodes, Integer type) throws Exception {
        UcSysRoleBean condition = new UcSysRoleBean();
        condition.setCodes(roleCodes);
        List<UcSysRoleBean> sysRoleList = userCenterMainDataService.selectUcSysRole(condition);

        List<Integer> roleIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(sysRoleList)) {
            for (UcSysRoleBean sysRoleBean : sysRoleList) {
                roleIds.add(sysRoleBean.getId());
            }
        }
        List<UcSysRoleMenuBean> sysRoleMenuList = getSysRoleMenuList(roleIds);
        List<Integer> menuIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(sysRoleMenuList)) {
            for (UcSysRoleMenuBean sysRoleMenuBean : sysRoleMenuList) {
                menuIds.add(sysRoleMenuBean.getMenuId());
            }
        }

        List<UcSysMenuBean> sysMenuList = getSysMenuList(menuIds, 0, type);
        sysMenuList.sort(Ordering.natural().onResultOf(UcSysMenuBean::getSort));

        List<SysMenu> result = convert(sysMenuList);
        return result;
    }

    @Override
    public void saveOrUpdate(SysMenu sysMenu) throws Exception {
        if (sysMenu.getId() == null) {
            UcSysMenuBean bean = new UcSysMenuBean();
            BeanUtils.copyProperties(sysMenu, bean);
            userCenterMainDataService.saveUcSysMenu(bean);
            return;
        }
        UcSysMenuBean condition = new UcSysMenuBean();
        condition.setId(sysMenu.getId());
        List<UcSysMenuBean> sysMenuList = userCenterMainDataService.selectUcSysMenu(condition);
        if (!CollectionUtils.isEmpty(sysMenuList)) {
            UcSysMenuBean sysMenuBean = sysMenuList.get(0);
            BeanUtils.copyProperties(sysMenu, sysMenuBean);
            userCenterMainDataService.updateUcSysMenu(sysMenuBean);
        }
    }

    @Override
    public List<SysMenu> findAll() throws Exception {
        UcSysMenuBean condition = new UcSysMenuBean();
        List<UcSysMenuBean> sysMenuList = userCenterMainDataService.selectUcSysMenu(condition);
        sysMenuList.sort(Ordering.natural().onResultOf(UcSysMenuBean::getSort));

        List<SysMenu> result = convert(sysMenuList);
        return result;
    }

    public List<SysMenu> convert(List<UcSysMenuBean> sysMenuList) {
        List<SysMenu> result = new ArrayList<>();
        for (UcSysMenuBean bean : sysMenuList) {
            SysMenu sysMenu = new SysMenu();
            BeanUtils.copyProperties(bean, sysMenu);
            sysMenu.setHidden(bean.getHidden() == 0 ? false : true);
            result.add(sysMenu);
        }
        return result;
    }

    /**
     * 查询所有一级菜单
     */
    @Override
    public List<SysMenu> findOnes() throws Exception {
        UcSysMenuBean condition = new UcSysMenuBean();
        condition.setType(1);
        List<UcSysMenuBean> sysMenuList = userCenterMainDataService.selectUcSysMenu(condition);
        sysMenuList.sort(Ordering.natural().onResultOf(UcSysMenuBean::getSort));

        List<SysMenu> result = convert(sysMenuList);
        return result;
    }
}
